package com.mega.fe.util.klass;

import com.mega.fe.util.MEGA;
import com.mega.fe.util.UnsafeUtil;
import com.mega.fe.asm.*;

import java.io.IOException;
import java.lang.reflect.Modifier;
import java.util.Arrays;
import java.util.Map;
import java.util.jar.Manifest;

public class InfoUtil {
    public static final ClassWriter INFO_CLASSWRITER = new ClassWriter(0);
    public static final ClassVisitor INFO_CLASS_VISITOR = new ClassVisitor(Opcodes.ASM7, INFO_CLASSWRITER) {
        @Override
        public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) {
            super.visit(version, access, name, signature, superName, interfaces);

            System.out.printf("目标类:%s开始读取%n.  -访问标记:%s,%n  -JAVA编译版本:%d,%n  -超类:%s,  -实现接口:%s%n", name, Modifier.toString(access), version -44, superName, Arrays.toString(interfaces));

        }

        @Override
        public void visitSource(String source, String debug) {
            super.visitSource(source, debug);
        }

        @Override
        public ModuleVisitor visitModule(String name, int access, String version) {
            return super.visitModule(name, access, version);
        }

        @Override
        public void visitNestHost(String nestHost) {
            super.visitNestHost(nestHost);
        }

        @Override
        public void visitOuterClass(String owner, String name, String descriptor) {
            super.visitOuterClass(owner, name, descriptor);
        }

        @Override
        public AnnotationVisitor visitAnnotation(String descriptor, boolean visible) {
            return super.visitAnnotation(descriptor, visible);
        }

        @Override
        public AnnotationVisitor visitTypeAnnotation(int typeRef, TypePath typePath, String descriptor, boolean visible) {
            return super.visitTypeAnnotation(typeRef, typePath, descriptor, visible);
        }

        @Override
        public void visitAttribute(Attribute attribute) {
            super.visitAttribute(attribute);
        }

        @Override
        public void visitNestMember(String nestMember) {
            super.visitNestMember(nestMember);
        }

        @Override
        public void visitPermittedSubclass(String permittedSubclass) {
            super.visitPermittedSubclass(permittedSubclass);
        }

        @Override
        public void visitInnerClass(String name, String outerName, String innerName, int access) {
            super.visitInnerClass(name, outerName, innerName, access);
        }

        @Override
        public RecordComponentVisitor visitRecordComponent(String name, String descriptor, String signature) {
            return super.visitRecordComponent(name, descriptor, signature);
        }

        @Override
        public FieldVisitor visitField(int access, String name, String descriptor, String signature, Object value) {
            return super.visitField(access, name, descriptor, signature, value);
        }

        @Override
        public MethodVisitor visitMethod(int access, String name, String descriptor, String signature, String[] exceptions) {
            return super.visitMethod(access, name, descriptor, signature, exceptions);
        }
    };

    public static void visit(Class<?> target) {
        try {

            ClassReader cr;
            String name = target.getName();
            boolean isDynamic = KlassCreator.CREATED_CLASSES.containsKey(name);
            if (isDynamic)
                KlassCreator.CREATED_CLASSES.put(target.getName(), new KlassCreator.ClassInfo(Map.of(target.getName(), MEGA.bytesOfClass(target))));
            cr = isDynamic ? new ClassReader(KlassCreator.CREATED_CLASSES.get(name).map().get(name)) : new ClassReader(name);
            cr.accept(INFO_CLASS_VISITOR, 0);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
}
